﻿using System;
using System.Collections.Specialized;
using System.Text;
using Microsoft.SharePoint.StsAdmin;
using Microsoft.SharePoint.Administration;

namespace Trentacular.SharePoint.StsAdmin
{
    public abstract class BaseStsadmCommand : ISPStsadmCommand
    {
        #region ISPStsadmCommand Members

        public virtual string GetHelpMessage(string command)
        {
            Initialize();

            var output = new StringBuilder();

            bool isFirst = true;
            foreach (var parameter in Parameters.Values)
            {
                var paramUsage = new StringBuilder();
                paramUsage.AppendFormat("-{0}", parameter.Name);

                if (parameter.Type != ParameterType.Flag)
                    paramUsage.AppendFormat(" <{0}>", parameter.Description);

                if (parameter.Type != ParameterType.Required)
                    paramUsage.Insert(0, "[").Append("]");

                if (!isFirst)
                    output.Append("\t");

                output.AppendLine(paramUsage.ToString());

                isFirst = false;
            }

            return output.ToString();
        }

        public int Run(string command, StringDictionary arguments, out string output)
        {
            Initialize();

            SetParameterValues(arguments);

            ValidateParameters();

            Execute();

            Console.WriteLine();

            output = (ErrorCount == 0) ?
                string.Empty :
                string.Format(
                    "The {0} command completed with {1} error{2}",
                    command,
                    ErrorCount,
                    (ErrorCount == 1) ? string.Empty : "s"
                    );
            
            return 0;
        }

        #endregion

        protected int ErrorCount = 0;

        protected ParameterDictionary Parameters { get; private set; }

        private void Initialize()
        {
            Parameters = new ParameterDictionary();
            CreateParameters();
        }

        private void SetParameterValues(StringDictionary arguments)
        {
            foreach (string paramName in arguments.Keys)
            {
                if ("o".Equals(paramName))
                    continue;

                if (!Parameters.ContainsKey(paramName))
                    throw new ArgumentException("Invalid Parameter: " + paramName);

                var param = Parameters[paramName];
                param.IsSpecified = true;
                param.Value = arguments[paramName];
            }
        }

        protected abstract void CreateParameters();
        
        protected abstract void ValidateParameters();

        protected abstract void Execute();

        private SPWebService _farmWebService;
        protected SPWebService FarmWebService
        {
            get
            {
                if (_farmWebService == null)
                    _farmWebService = SPFarm.Local.Services.GetValue<SPWebService>("");
                return _farmWebService;
            }
        }
    }
}
